package com.ocean.linkedlist;

/**
 * https://leetcode.cn/problems/reverse-nodes-in-k-group/
 */
public class ReverseNodesInKGroup {

    public static void main(String[] args) {
        ListNode e5 = new ListNode(5, null);
        ListNode e4 = new ListNode(4, e5);
        ListNode e3 = new ListNode(3, e4);
        ListNode e2 = new ListNode(2, e3);
        ListNode e1 = new ListNode(1, e2);
        ListNode.print(e1);
        ListNode reverse = new ReverseNodesInKGroup().reverseKGroup(e1,3);
        ListNode.print(reverse);
    }

    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null || k == 0) {
            return head;
        }
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode pre = dummy;
        ListNode cur = dummy;
        while (cur.next != null) {
            for (int i = 0; i < k && cur != null; i++) {
                cur = cur.next;
            }
            if (cur == null) { // 循环次数够了 但是最后那个是null 说明元素不够
                break;
            }
            // 获取了一组 这一组的头部是 pre 尾部是 cur
            ListNode next = cur.next; // 这个是下一组的头部
            cur.next = null; // 将这一组的尾部指向null 便于反转
            // 上一组的尾部 要指向这一组的头部(反转后就是头部)
            ListNode start = pre.next;
            pre.next = reverse(start);

            // 从这一组的尾部开始
            start.next = next;
            pre = start;
            cur = pre; // 要记录头在哪里
        }
        return dummy.next;
    }

    public ListNode reverse(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
